#pragma once
#include"reverse_iterator.h"
namespace ljw
{
	template<class T>
	struct List_Node
	{
		T _data;
		List_Node* prev;
		List_Node* next;
		List_Node(const T&x=T())
			:_data(x)
			,prev(nullptr)
			,next(nullptr)
		{}
	};
	template<class T,class Ref,class Ptr>
	struct __List_iterator
	{
		typedef List_Node<T> Node;
		typedef __List_iterator<T,Ref,Ptr> self;
		Node* _node;
		__List_iterator(Node* node)
			:_node(node)
		{}
		self& operator++()
		{
			_node = _node->next;
			return *this;
		}
		self operator++(int)
		{
			self tmp(*this);
			_node = _node->next;
			return tmp;
		}
		self& operator--()
		{
			_node = _node->prev;
			return *this;
		}
		self operator--(int)
		{
			self tmp(*this);
			_node = _node->prev;

			return tmp;
		}
		Ref operator*()
		{
			return _node->_data;
		}
		Ptr operator->()
		{
			return &(_node->_data);
		}
		bool operator!=(const self& s)
		{
			return _node != s._node;
		}
		bool operator==(const self& s)
		{
			return _node == s._node;
		}

	};

	template<class T, class Ref, class Ptr>
	struct __reverse_iterator
	{
		typedef List_Node<T> Node;
		typedef __reverse_iterator<T, Ref, Ptr> self;
		Node* _node;
		__reverse_iterator(Node* node)
			:_node(node)
		{}
		self& operator++()
		{
			_node = _node->prev;
			return *this;
		}
		self operator++(int)
		{
			self tmp(*this);
			_node = _node->prev;
			return tmp;
		}
		self& operator--()
		{
			_node = _node->next;
			return *this;
		}
		self operator--(int)
		{
			self tmp(*this);
			_node = _node->next;

			return tmp;
		}
		Ref operator*()
		{
			return _node->_data;
		}
		Ptr operator->()
		{
			return &(_node->_data);
		}
		bool operator!=(const self& s)
		{
			return _node != s._node;
		}
		bool operator==(const self& s)
		{
			return _node == s._node;
		}

	};
	template<class T>
	class list
	{
	public:
		typedef List_Node<T> Node;
		typedef __List_iterator<T,T&,T*> iterator;
		typedef __List_iterator<T, const T&, const T*> const_iterator;
		//typedef __reverse_iterator<T, T&, T*> reverse_iterator;
		typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
		typedef ReverseIterator<const_iterator,const T&,const T*> const_reverse_iterator;
		reverse_iterator rbegin()
		{
			return reverse_iterator(--end());
		}
		reverse_iterator rend()
		{
			return reverse_iterator(end());
		}
		const_reverse_iterator rbegin()const
		{
			return const_reverse_iterator(--end());
		}
		const_reverse_iterator rend()const
		{
			return const_reverse_iterator(end());
		}
		void empty_init()
		{
			_head = new Node;
			_head->next = _head;
			_head->prev = _head;
			_size = 0;
		}
		list()
		{
			
			empty_init();
		}
		void swap(list<T>&lt)
		{
			std::swap(_head, lt._head);
			std::swap(_size, lt._size);
		}
		//l3(l2)
		list(const list<T>& lt)
		{
			empty_init();
			for (auto e : lt)
			{
				push_back(e);
			}
		}
		//l3=l1
		list<T>& operator=(const list<T>& lt)
		//list<T>& operator=( list<T>& lt)
		{
			if (this != &lt)
			{
				clear();
				for (auto e : lt)
				{
					push_back(e);
				}
			}
			return *this;
		}
		/*list<T>& operator=(list tmp)
		{
			swap(tmp);
			return *this;
		}*/
		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}
		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}
		/*reverse_iterator rbegin()
		{
			return _head->prev;
		}
		reverse_iterator rend()
		{
			return _head;
		}*/
		iterator begin()
		{
			return _head->next;
		}
		iterator end()
		{
			return _head;
		}
		const_iterator begin()const
		{
			return _head->next;
		}
		const_iterator end()const
		{
			return _head;
		}
		void push_back(const T& x)
		{
			insert(end(), x);
		}
		void push_front(const T& x)
		{
			insert(begin(), x);
		}
		void pop_front()
		{
			erase(begin());
		}
		void pop_back()
		{
			erase(--end());
		}
		iterator insert(iterator pos, const T& x)
		{
			Node* newnode = new Node(x);
			Node* cur = pos._node;
			Node* prev = cur->prev;
			prev->next = newnode;
			newnode->prev = prev;

			newnode->next = cur;
			cur->prev = newnode;
			_size++;
			return iterator(newnode);
		}
		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* prev = cur->prev;
			Node* next = cur->next;
			delete cur;

			prev->next = next;
			next->prev = prev;
			
			_size--;
			return iterator(next);
		}
		size_t size()
		{
			return _size;
		}
	private:
		Node* _head;
		size_t _size;
	};
	/*void Test_list1()
	{
		list<int> It;
		It.push_back(1);
		It.push_back(2);
		It.push_back(3);
		It.push_back(4);
		It.push_back(5);
		list<int>::iterator it = It.begin();
		while (it != It.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}
	void Test_list2()
	{
		list<int> It;
		It.push_back(1);
		It.push_back(2);
		It.push_back(3);

		It.insert(It.begin(), 10);

		for (auto e : It)
		{
			cout << e << " ";
		}
		cout << endl;
		It.erase(It.begin());
		for (auto e : It)
		{
			cout << e << " ";
		}
		cout << endl;
		It.pop_back();
		for (auto e : It)
		{
			cout << e << " ";
		}
		cout << endl;
	}
	void Test_list3()
	{
		list<int> It;
		It.push_back(1);
		It.push_back(2);
		It.push_back(3);
		for (auto e : It)
		{
			cout << e << " ";
		}
		cout << endl;
		list<int> It1(It);
		for (auto e : It1)
		{
			cout << e << " ";
		}
		cout << endl;
		It1 = It;
		for (auto e : It1)
		{
			cout << e << " ";
		}
		cout << endl;
	}
	template<typename Cantainer>
	void print_cantainer(const Cantainer&con)
	{
		typename Cantainer::const_iterator it = con.begin();
		while (it != con.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;
	}
	void Test_list4()
	{
		list<int> It;
		It.push_back(1);
		It.push_back(2);
		It.push_back(3);
		print_cantainer(It);

		vector<string> s;
		s.push_back("11111111111");
		s.push_back("11111111111");
		s.push_back("11111111111");
		print_cantainer(s);
	}
	void Test_list5()
	{
		list<int> It;
		It.push_back(1);
		It.push_back(2);
		It.push_back(3);

		list<int>::reverse_iterator rit = It.rbegin();
		while (rit != It.rend())
		{
			cout << *rit << " ";
			++rit;
		}
		cout << endl;
	}*/
}

